#include <string>
#include <thread>
#include <mutex>
#include <chrono>
#include <gflags/gflags.h>
#include "../../log/log.h"

std::mutex mtx;

/*直接使用锁*/
void funtion(char w){
    LOG("lock %c", w);
    // 调用时锁的状态：未锁，则锁上
    // 调用时锁的状态：已锁，则阻塞等待解锁
    mtx.lock();
    // 调用时锁的状态：未锁，则锁上，并返回true
    // 调用时锁的状态：已锁，则直接返回false
    // if (mtx.try_lock() == true) {...}
    LOG("funtion%c start", w);
    for ( int i = 0; i < 3; i++)
    {
        LOG("funtion%c %d", w, i);
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    LOG("funtion%c end", w);
    mtx.unlock();
}

/*借助unique_lock高级的使用锁*/
// void funtion(char w){
//     LOG("lock %c", w);
//     // 一经构造实例就会锁起，可主动调用unlock解锁；可在析构时自动解锁
//     // 再创建就会阻塞等待，直到上一个创建的实例解锁
//     std::unique_lock<std::mutex> lck (mtx);
//     // 调用try_lock
//     // std::unique_lock<std::mutex> lck (mtx, std::try_to_lock);
//     // if (lck.owns_lock()) {...}
//     // 不锁
//     // std::unique_lock<std::mutex> lck (mtx, std::defer_lock);
//     LOG("funtion%c start", w);
//     for ( int i = 0; i < 3; i++)
//     {
//         LOG("funtion%c %d", w, i);
//         std::this_thread::sleep_for(std::chrono::seconds(1));
//     }
//     LOG("funtion%c end", w);
// }

int main(int argc, char* argv[]) {
    gflags::SetUsageMessage(__DATE__ " " __TIME__ "\n多线程demo");
    gflags::SetVersionString("0.1");
    gflags::ParseCommandLineFlags(&argc, &argv, true);

    /*thread 一经构建就会开始run，并不是join/detach调用时run*/
    LOG("init threadA start.");
    std::thread threadA(funtion, 'A');
    LOG("init threadB start.");
    std::thread threadB(funtion, 'B');
    LOG("init end.\n");

    /*join 阻塞等待thread结束退出*/
    LOG("threadA.join start.");
    threadA.join();
    LOG("threadB.join start.");
    threadB.join();
    LOG("join end.\n");
    
    LOG("program end.");

    return 0;
}